package com.mysen.sso.controller;

import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.mysen.exception.MaikeServiceException;
import com.mysen.model.BaseModel;
import com.mysen.model.Response;
import com.mysen.spring.plugin.WebContextUtil;
import com.mysen.sso.cache.SessionCache;
import com.mysen.sso.model.Permission;
import com.mysen.sso.model.User;
import com.mysen.sso.service.UserService;
import com.mysen.sso.thirdclient.WxLoginService;

@RequestMapping("/login")
@Controller
public class LoginController {

	private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);
	
	@Reference
	private UserService userService;
	
	@Autowired
	private SessionCache sessionCache;
	
	@Autowired
	private HttpServletRequest request;
	
	@Autowired
	private HttpServletResponse response;
	
	@Autowired
	private WxLoginService wxservice;
	
	@PostMapping("wx")
	@ResponseBody
	public Response<?> loginWx(@RequestParam("jscode") String js_code, @RequestBody User param, @CookieValue("sid") String sid) throws Exception{
		if(!StringUtils.hasText(sid)){
			Cookie cookie = new Cookie("sid", sid = request.getSession().getId());
			cookie.setPath("/");
			response.addCookie(cookie);
		}
		
		JSONObject object = wxservice.login(js_code);
		request.getSession().setAttribute("session_key", object.getString("session_key"));
		param.setOpenId(object.getString("openid"));
		User user = userService.loginByOpenId(param);
		List<Permission> permissions = userService.selectPermissions(user);
		sessionCache.putUser(request, user, permissions);
		return getUsers(sid);
	}
	@Value("${spring.mvc.domain}")
	private String domain;
	
	@PostMapping
	@ResponseBody
	public Response<?> login(@RequestBody User param){
		if(!StringUtils.hasText(param.getUsername())) {
			throw new MaikeServiceException(Response.MSG_PARAM_ERROR);
		}
		if(!StringUtils.hasText(param.getPassword())) {
			throw new MaikeServiceException(Response.MSG_PARAM_ERROR);
		}
		LOGGER.info("user : {} login...", param.getUsername());
		String sid = WebContextUtil.getSid(request);
		if(!StringUtils.hasText(sid)){
			Cookie cookie = new Cookie("sid", sid = request.getSession().getId());
			cookie.setPath("/");
			cookie.setDomain(domain);
			response.addCookie(cookie);
		}
		User user = userService.loginByWeb(param);
		if(user != null) {
			List<Permission> permissions = userService.selectPermissions(user);
			sessionCache.putUser(request, user, permissions);
			Response<?> users = getUsers(sid);
			users.setDatas(permissions);
			return users;
		}else {
			throw new MaikeServiceException(Response.MSG_PARAM_ERROR);
		}
	}
	
	@GetMapping
	@ResponseBody
	public Response<?> getUsers(@CookieValue("sid") String sid){
		Response<User> resp = new Response<>();
		User curUser = sessionCache.getUser(request);
		resp.setSuccess(curUser.getStatus().equals(BaseModel.Status.ALLOW));
		resp.setData(curUser);
		return resp;
	}
	
	@DeleteMapping
	@ResponseBody
	public Response<?> logout(@CookieValue("sid") String sid){
		Response<User> resp = new Response<>();
		resp.setSuccess(true);
		sessionCache.remove(sid);
		return resp;
	}
	
	@PutMapping
	@ResponseBody
	public Response<?> update(@RequestBody User user, @CookieValue("sid") String sid){
		Response<User> resp = new Response<>();
		user.setRoles(null);
		User curUser = sessionCache.getUser(request);
		if(curUser == null) {
			resp.setErrorMsg(Response.MSG_UNLOGIN);
			resp.setSuccess(false);
			return resp;
		}
		user.setUserId(curUser.getUserId());
		userService.updateById(user);
		resp.setSuccess(true);
		return resp;
	}
}
